package com.dx.VegetableOxygenBarBackEnd.websocket;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.dx.VegetableOxygenBarBackEnd.model.domain.entity.Messages;
import com.dx.VegetableOxygenBarBackEnd.service.MessagesService;
import com.dx.VegetableOxygenBarBackEnd.utils.SpringContext;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@ServerEndpoint(value ="/websocket/{roomId}/{userId}", configurator = CustomConfigurator.class)
@Component
public class WebSocket {

    // 房间的 WebSocket 连接管理，key 为 roomId，value 为房间中的所有 WebSocket 连接
    private static ConcurrentHashMap<String, Set<WebSocket>> roomMap = new ConcurrentHashMap<>();

    private MessagesService messagesService;
    private Session session;  // 当前 WebSocket session
    private String roomId;    // 当前连接的房间 ID
    private String userId;    // 当前连接的用户 ID

    // 广播消息到房间中的所有 WebSocket 连接
    public static void broadcastMessage(String message, String roomId) {
        Set<WebSocket> room = roomMap.get(roomId);
        if (room != null) {
            for (WebSocket webSocket : room) {
                try {
                    webSocket.session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    // 主动向客户端发送消息
    public void sendMessage() {
        // 获取当前房间的 WebSocket 实例
        Set<WebSocket> room = roomMap.get(roomId);
        if (room != null) {
            for (WebSocket webSocket : room) {
                // 发送给当前用户
                if (webSocket.userId.equals(this.userId)) {
                    try {
                        // 假设 roomId 包含发送者和接收者的ID（"sendId-receiveId"格式）
                        String[] users = roomId.split("-");
                        String user1 = users[0];
                        String user2 = users[1];

                        // 查询 1 给 2 发送的未读消息
                        List<Messages> user1ToUser2Messages = messagesService.getUnreadMessagesForReceiver(
                                Integer.parseInt(user2),  // 接收者是 user2
                                Integer.parseInt(user1)   // 发送者是 user1
                        );

                        // 查询 2 给 1 发送的未读消息
                        List<Messages> user2ToUser1Messages = messagesService.getUnreadMessagesForReceiver(
                                Integer.parseInt(user1),  // 接收者是 user1
                                Integer.parseInt(user2)   // 发送者是 user2
                        );

                        // 合并两个列表
                        List<Messages> allUnreadMessages = new ArrayList<>();
                        allUnreadMessages.addAll(user1ToUser2Messages);
                        allUnreadMessages.addAll(user2ToUser1Messages);
                        // 按照 timestamp 字段进行排序
                        allUnreadMessages.sort(Comparator.comparing(Messages::getTimestamp));
                        // 如果有未读消息，逐条发送给前端
                        if (!allUnreadMessages.isEmpty()) {
                            for (Messages msg : allUnreadMessages) {
                                // 发送消息给客户端
                                webSocket.session.getBasicRemote().sendText(JSONUtil.toJsonStr(msg));
                                System.out.println("【websocket消息】发送未读消息,用户=" + this.userId + ", 消息内容: " + msg.getMessageText());

                                // 更新消息为已读
                                msg.setIsRead(1);  // 标记为已读
                                messagesService.updateById(msg);  // 更新数据库中的记录
                            }
                        } else {
                            // 如果没有未读消息，发送一个连接成功的消息
                            webSocket.session.getBasicRemote().sendText("欢迎，您已成功连接到房间 " + roomId);
                            System.out.println("【websocket消息】用户 " + this.userId + " 已连接到房间 " + roomId);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }





    @OnOpen
    public void onOpen(Session session, @PathParam("roomId") String roomId, @PathParam("userId") String userId) {
        this.session = session;
        this.roomId = roomId;
        this.userId = userId;

        // 获取 MessagesService
        this.messagesService = SpringContext.getBean(MessagesService.class);

        // 将当前用户添加到房间
        roomMap.putIfAbsent(roomId, new HashSet<>());
        roomMap.get(roomId).add(this);

        // 发送成功连接通知
        System.out.println("用户 " + userId + " 已连接到房间 " + roomId);

        // 调用 sendMessage，发送未读消息或欢迎消息
        sendMessage();
    }

    //接受客户端传过来的数据
    @OnMessage
    public void onMessage(String message) {
        try {
            System.out.println("收到消息: " + message);
            // 解析收到的 JSON 消息
            JSONObject json = JSONUtil.parseObj(message);

            Integer receiverId = json.getInt("receiverId");
            String messageText = json.getStr("messageText");
            Integer senderId = json.getInt("senderId");

            //发送消息之前先将之前的对面用户发送的消息全部标记为已读
//            List<Messages> unreadMessages = messagesService.getUnreadMessagesForReceiver(receiverId, senderId);
//            if (!unreadMessages.isEmpty()) {
//                for (Messages unreadMsg : unreadMessages) {
//                    unreadMsg.setIsRead(1);  // 标记为已读
//                    messagesService.updateById(unreadMsg);  // 更新数据库
//                }
//            }

            // 保存消息到数据库
            Messages msg = new Messages();
            msg.setSenderId(senderId);
            msg.setReceiverId(receiverId);
            msg.setMessageText(messageText);
            msg.setTimestamp(new Date());
            msg.setIsRead(0);  // 默认未读
            messagesService.save(msg);

            // 构建要发送的消息内容（可以根据需求调整）
            JSONObject response = new JSONObject();
            response.put("senderId", senderId);
            response.put("messageText", messageText);
            response.put("timestamp", new Date().toString());
            response.put("isRead", 0);

            // 广播消息给房间内的所有用户
            broadcastMessage(response.toString(), roomId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnClose
    public void onClose() {
        // 用户断开连接时，从房间中移除
        Set<WebSocket> room = roomMap.get(roomId);
        if (room != null) {
            room.remove(this);
            if (room.isEmpty()) {
                roomMap.remove(roomId);  // 如果房间内没有人，移除房间
            }
        }
        System.out.println("用户 " + userId + " 已断开连接");
    }

    @OnError
    public void onError(Session session, Throwable error) {
        System.err.println("WebSocket 错误: " + error.getMessage());
        error.printStackTrace();
    }
}
